package com.gzc.just.play.last.war.centralserver.achievement;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 成就管理器 - 管理所有玩家的成就数据
 * 
 * @author AI编程助手
 * @version 1.0
 */
public class AchievementManager {
    
    private final Map<Integer, AchievementConfig> achievementConfigs = new ConcurrentHashMap<>();
    private final Map<Long, Map<Integer, PlayerAchievement>> playerAchievements = new ConcurrentHashMap<>();
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final List<AchievementListener> listeners = new CopyOnWriteArrayList<>();
    
    /**
     * 注册成就配置
     * 
     * @param config 成就配置
     */
    public void registerAchievement(AchievementConfig config) {
        if (config != null) {
            achievementConfigs.put(config.getAchievementId(), config);
        }
    }
    
    /**
     * 获取成就配置
     * 
     * @param achievementId 成就ID
     * @return 成就配置
     */
    public AchievementConfig getAchievementConfig(int achievementId) {
        return achievementConfigs.get(achievementId);
    }
    
    /**
     * 获取玩家的成就
     * 
     * @param playerId 玩家ID
     * @param achievementId 成就ID
     * @return 玩家成就
     */
    public PlayerAchievement getPlayerAchievement(long playerId, int achievementId) {
        lock.readLock().lock();
        try {
            Map<Integer, PlayerAchievement> playerAchs = playerAchievements.get(playerId);
            if (playerAchs != null) {
                return playerAchs.get(achievementId);
            }
            return null;
        } finally {
            lock.readLock().unlock();
        }
    }
    
    /**
     * 获取玩家的所有成就
     * 
     * @param playerId 玩家ID
     * @return 成就列表
     */
    public List<PlayerAchievement> getPlayerAchievements(long playerId) {
        lock.readLock().lock();
        try {
            Map<Integer, PlayerAchievement> playerAchs = playerAchievements.get(playerId);
            if (playerAchs != null) {
                return new ArrayList<>(playerAchs.values());
            }
            return new ArrayList<>();
        } finally {
            lock.readLock().unlock();
        }
    }
    
    /**
     * 初始化玩家成就
     * 
     * @param playerId 玩家ID
     */
    public void initializePlayerAchievements(long playerId) {
        lock.writeLock().lock();
        try {
            if (!playerAchievements.containsKey(playerId)) {
                Map<Integer, PlayerAchievement> playerAchs = new ConcurrentHashMap<>();
                
                // 为所有成就创建玩家成就记录
                for (AchievementConfig config : achievementConfigs.values()) {
                    PlayerAchievement pa = new PlayerAchievement(playerId, config.getAchievementId(), config);
                    playerAchs.put(config.getAchievementId(), pa);
                }
                
                playerAchievements.put(playerId, playerAchs);
                notifyAchievementsInitialized(playerId);
            }
        } finally {
            lock.writeLock().unlock();
        }
    }
    
    /**
     * 更新成就进度
     * 
     * @param playerId 玩家ID
     * @param achievementId 成就ID
     * @param delta 增加的值
     * @return 是否完成了成就
     */
    public boolean updateAchievementProgress(long playerId, int achievementId, int delta) {
        lock.writeLock().lock();
        try {
            PlayerAchievement pa = getPlayerAchievement(playerId, achievementId);
            if (pa == null) {
                // 如果成就不存在，先初始化
                AchievementConfig config = achievementConfigs.get(achievementId);
                if (config != null) {
                    Map<Integer, PlayerAchievement> playerAchs = playerAchievements.get(playerId);
                    if (playerAchs != null) {
                        pa = new PlayerAchievement(playerId, achievementId, config);
                        playerAchs.put(achievementId, pa);
                    }
                }
            }
            
            if (pa != null) {
                boolean completed = pa.addProgress(delta);
                if (completed) {
                    notifyAchievementCompleted(playerId, achievementId);
                } else {
                    notifyAchievementProgress(playerId, achievementId, pa.getCurrentProgress());
                }
                return completed;
            }
            return false;
        } finally {
            lock.writeLock().unlock();
        }
    }
    
    /**
     * 领取成就奖励
     * 
     * @param playerId 玩家ID
     * @param achievementId 成就ID
     * @return 是否成功领取
     */
    public boolean claimAchievementReward(long playerId, int achievementId) {
        lock.writeLock().lock();
        try {
            PlayerAchievement pa = getPlayerAchievement(playerId, achievementId);
            if (pa != null && pa.claimReward()) {
                notifyAchievementRewardClaimed(playerId, achievementId, 
                                             pa.getConfig().getRewardPoints(),
                                             pa.getConfig().getRewardGold());
                return true;
            }
            return false;
        } finally {
            lock.writeLock().unlock();
        }
    }
    
    /**
     * 获取玩家已完成的成就列表
     * 
     * @param playerId 玩家ID
     * @return 已完成的成就列表
     */
    public List<PlayerAchievement> getCompletedAchievements(long playerId) {
        lock.readLock().lock();
        try {
            List<PlayerAchievement> completed = new ArrayList<>();
            Map<Integer, PlayerAchievement> playerAchs = playerAchievements.get(playerId);
            if (playerAchs != null) {
                for (PlayerAchievement pa : playerAchs.values()) {
                    if (pa.isCompleted()) {
                        completed.add(pa);
                    }
                }
            }
            return completed;
        } finally {
            lock.readLock().unlock();
        }
    }
    
    /**
     * 获取玩家未领取奖励的成就列表
     * 
     * @param playerId 玩家ID
     * @return 未领取奖励的成就列表
     */
    public List<PlayerAchievement> getUnclaimedAchievements(long playerId) {
        lock.readLock().lock();
        try {
            List<PlayerAchievement> unclaimed = new ArrayList<>();
            Map<Integer, PlayerAchievement> playerAchs = playerAchievements.get(playerId);
            if (playerAchs != null) {
                for (PlayerAchievement pa : playerAchs.values()) {
                    if (pa.canClaimReward()) {
                        unclaimed.add(pa);
                    }
                }
            }
            return unclaimed;
        } finally {
            lock.readLock().unlock();
        }
    }
    
    /**
     * 获取玩家的成就完成度百分比
     * 
     * @param playerId 玩家ID
     * @return 完成度（0-100）
     */
    public int getAchievementCompletionPercentage(long playerId) {
        lock.readLock().lock();
        try {
            Map<Integer, PlayerAchievement> playerAchs = playerAchievements.get(playerId);
            if (playerAchs == null || playerAchs.isEmpty()) {
                return 0;
            }
            
            int completed = 0;
            for (PlayerAchievement pa : playerAchs.values()) {
                if (pa.isCompleted()) {
                    completed++;
                }
            }
            
            return (completed * 100) / playerAchs.size();
        } finally {
            lock.readLock().unlock();
        }
    }
    
    /**
     * 添加监听器
     * 
     * @param listener 监听器
     */
    public void addListener(AchievementListener listener) {
        if (listener != null) {
            listeners.add(listener);
        }
    }
    
    /**
     * 移除监听器
     * 
     * @param listener 监听器
     */
    public void removeListener(AchievementListener listener) {
        listeners.remove(listener);
    }
    
    private void notifyAchievementsInitialized(long playerId) {
        for (AchievementListener listener : listeners) {
            listener.onAchievementsInitialized(playerId);
        }
    }
    
    private void notifyAchievementProgress(long playerId, int achievementId, int progress) {
        for (AchievementListener listener : listeners) {
            listener.onAchievementProgress(playerId, achievementId, progress);
        }
    }
    
    private void notifyAchievementCompleted(long playerId, int achievementId) {
        for (AchievementListener listener : listeners) {
            listener.onAchievementCompleted(playerId, achievementId);
        }
    }
    
    private void notifyAchievementRewardClaimed(long playerId, int achievementId, int points, int gold) {
        for (AchievementListener listener : listeners) {
            listener.onAchievementRewardClaimed(playerId, achievementId, points, gold);
        }
    }
    
    /**
     * 成就监听器接口
     */
    public interface AchievementListener {
        void onAchievementsInitialized(long playerId);
        void onAchievementProgress(long playerId, int achievementId, int progress);
        void onAchievementCompleted(long playerId, int achievementId);
        void onAchievementRewardClaimed(long playerId, int achievementId, int points, int gold);
    }
}
